package org.best.queue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 数组模拟队列,FIFO(先进先出)
 */
public class Queue<E> {
    private Logger log = LoggerFactory.getLogger(Queue.class);

    //队列长度
    private int size;
    //头指针,默认为0
    private int front;
    //尾指针,默认为0
    private int rear;
    //队列底层数组
    private Object[] array;
    //底层数组长度,不指定则默认为10
    private int length;

    public Queue(int length) {
        this.length = length;
        this.array = new Object[length];
    }

    public Queue() {
        this.length = 10;
        this.array = new Object[length];
    }

    /**
     * 添加元素
     * @param data
     */
    public boolean push(E data) {
        add(data);
        return true;
    }

    /**
     * 删除队列最前端的元素
     * @return
     */
    public boolean pop() {
        del();
        return true;
    }


    private void del() {
        if(checkFront()) {
            front++;
            size--;
            return;
        }
        log.debug("删除元素失败");
    }

    /**
     * 获取队列中的元素个数
     * @return
     */
    public int size(){
        return size;
    }

    /**
     * 获取队列头元素
     * @return
     */
    public E getIndex(){
        return (E)array[front];
    }

    /**
     * 获取队列尾元素
     * @return
     */
    public E getLast(){
        return (E)array[rear-1];
    }

    /**
     * 获取队列中所有有效元素
     * @return
     */
    public List<E> getAll(){
        List<E> list = new ArrayList<>();
        for (int i = front; i < rear; i++) {
            list.add((E)array[i]);
        }
        return list;
    }



    private void add(E data) {
        if (checkPosition()) {
            array[rear] = data;
            rear++;
            size++;
            return;
        }
        log.debug("添加元素"+data+"失败");
    }

    /**
     * 校验 rear(尾指针)是否合法
     *
     */
    private boolean checkPosition() {
        if (rear < 0) {
            log.info("[rear]字段输入不合法");
            return false;
        }
        if(rear == length){
            log.info("队列已满");
            return false;
        }
        return true;
    }

    /**
     * 校验头指针
     *
     */
    private boolean checkFront() {
        if (front < 0) {
            log.info("[front]字段输入不合法");
            return false;
        }
        if(rear == front){
            log.info("队列已空");
            return false;
        }
        return true;
    }


}
